package com.java80.littlegame.service.game;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.java80.littlegame.common.base.BaseHandler;
import com.java80.littlegame.common.base.GameUser;
import com.java80.littlegame.common.base.ServiceStatus;
import com.java80.littlegame.common.base.ServiceStatusHelper;
import com.java80.littlegame.common.base.SystemConsts;
import com.java80.littlegame.common.base.SystemDataMgr;
import com.java80.littlegame.common.base.VertxMessageHelper;
import com.java80.littlegame.common.db.dao.DAOFactory;
import com.java80.littlegame.common.db.dao.URoomInfoDao;
import com.java80.littlegame.common.db.dao.UUserRoomInfoDao;
import com.java80.littlegame.common.db.entity.SGameConfig;
import com.java80.littlegame.common.db.entity.UUserRoomInfo;
import com.java80.littlegame.common.message.proto.BaseMsg;
import com.java80.littlegame.common.message.proto.ProtoHelper;
import com.java80.littlegame.common.message.proto.ProtoList;
import com.java80.littlegame.common.message.proto.cluster.ClusterMessage;
import com.java80.littlegame.common.message.proto.cluster.DeskEndMessage;
import com.java80.littlegame.common.message.proto.cluster.GameStartMessage;
import com.java80.littlegame.common.message.proto.game.DesktopEndMessage;
import com.java80.littlegame.common.message.proto.timer.DesktopExpridedMessage;
import com.java80.littlegame.service.game.desk.DeskSetting;
import com.java80.littlegame.service.game.desk.Desktop;
import com.java80.littlegame.service.game.desk.DesktopMgr;

public class GameHandler extends BaseHandler {
	final transient static Logger log = LoggerFactory.getLogger(GameHandler.class);

	@Override
	public Object onReceive(String obj) {
		if (obj instanceof String) {
			onMessage(ProtoHelper.parseJSON(obj.toString()));
		}
		return null;
	}

	private void onMessage(BaseMsg msg) {
		long userId = msg.getSenderUserId();
		switch (msg.getCode()) {
		case ProtoList.MSG_CODE_GAME_START:
			gameStart((GameStartMessage) msg);
			break;
		case ProtoList.MSG_CODE_DESKEND:
			deskend((DeskEndMessage) msg, 1);
			break;
		case ProtoList.MSG_CODE_TIMER_DESKTOPEXPRIDED:
			DeskEndMessage de = new DeskEndMessage();
			DesktopExpridedMessage dem = (DesktopExpridedMessage) msg;
			de.setRoomId(dem.getRoomId());
			deskend(de, 2);
			break;
		default:
			Desktop desktop = DesktopMgr.getDesktop(userId);
			if (desktop != null) {
				if (msg instanceof ClusterMessage) {
					desktop.onClusterMessage((ClusterMessage) msg);
				} else {
					desktop.onMessage(userId, msg);
				}
			}
			break;
		}
	}

	private void deskend(DeskEndMessage msg, int reason) {
		Desktop desktop = DesktopMgr.removeDesktop(msg.getRoomId());
		UUserRoomInfoDao d1 = DAOFactory.getUserRoomInfoDao();
		URoomInfoDao d2 = DAOFactory.getRoomInfoDao();
		try {
			d1.deleteByRoomId(msg.getRoomId());
			d2.delete(msg.getRoomId());
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// 发送消息
		DesktopEndMessage dem = new DesktopEndMessage();
		dem.setRoomId(msg.getRoomId());
		dem.setReason(reason);
		List<Long> playerIds = desktop.getSetting().getPlayerIds();
		for (long id : playerIds) {
			GameUser user = GameUser.getGameUser(id);
			dem.setRecUserId(id);
			VertxMessageHelper.sendMessageToGateWay(user, dem);
		}
		desktop = null;
	}

	private void gameStart(GameStartMessage msg) {
		int gameId = msg.getGameId();
		int roomId = msg.getRoomId();
		DeskSetting set = new DeskSetting();
		set.setGameId(gameId);
		set.setRoomId(roomId);
		UUserRoomInfoDao dao = DAOFactory.getUserRoomInfoDao();
		List<UUserRoomInfo> findByRoomId = null;
		try {
			findByRoomId = dao.findByRoomId(roomId);
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		List<Long> ids = new ArrayList<>();
		for (UUserRoomInfo uri : findByRoomId) {
			ids.add(uri.getUserId());
		}
		set.setPlayerIds(ids);
		TreeMap<Integer, SGameConfig> gameConfigs = SystemDataMgr.getGameConfigs();
		Desktop desk = null;
		try {
			Class<?> c = Class.forName(gameConfigs.get(gameId).getDesktopClass());
			Constructor<?> con = c.getConstructor(DeskSetting.class);
			desk = (Desktop) con.newInstance(set);
			DesktopMgr.addDesktop(roomId, desk, ids);
			desk.onStart();
			// TODO 添加定时器
			DesktopExpridedMessage em = new DesktopExpridedMessage();
			em.setDelay(gameConfigs.get(gameId).getExpride() * 1000);
			em.setGameId(gameId);
			em.setRoomId(roomId);
			em.setTargetQueue(GameConfig.getQueueName());
			ServiceStatus s = ServiceStatusHelper.randServiceStatus(SystemConsts.SERVICE_TYPE_QUARTZ);
			VertxMessageHelper.sendMessageToService(s.getServiceQueueName(), em.toString());
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}
